icon-theme: Add GTK_ICON_LOOKUP_LOAD_IN_THREAD flag
authorAlexander Larsson <alexl@redhat.com>
Fri, 7 Feb 2020 16:25:18 +0000 (17:25 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 7 Feb 2020 16:25:18 +0000 (17:25 +0100)
This causes lookup to trigger a thread that loads the icon texture.

gtk/gtkicontheme.c
gtk/gtkicontheme.h

index 1377abc192028d7563ae780b678e84bb13294152..45b580e6a2733aa1a00856b10125212cf1292908 100644 (file)
@@ -2185,6 +2185,20 @@ choose_icon (GtkIconTheme      *self,
   return icon;
 }
 
+static void
+load_icon_thread (GTask        *task,
+                  gpointer      source_object,
+                  gpointer      task_data,
+                  GCancellable *cancellable)
+{
+  GtkIconPaintable *self = GTK_ICON_PAINTABLE (source_object);
+
+  g_mutex_lock (&self->texture_lock);
+  icon_ensure_texture__locked (self, TRUE);
+  g_mutex_unlock (&self->texture_lock);
+  g_task_return_pointer (task, NULL, NULL);
+}
+
 /**
  * gtk_icon_theme_lookup_icon:
  * @self: a #GtkIconTheme
@@ -2258,6 +2272,26 @@ gtk_icon_theme_lookup_icon (GtkIconTheme       *self,
 
   gtk_icon_theme_unlock (self);
 
+  if (flags & GTK_ICON_LOOKUP_LOAD_IN_THREAD)
+    {
+      gboolean has_texture = FALSE;
+
+      /* If we fail to get the lock it is because some other thread is
+         currently loading the icon, so we need to do nothing */
+      if (g_mutex_trylock (&icon->texture_lock))
+        {
+          has_texture = icon->texture != NULL;
+          g_mutex_unlock (&icon->texture_lock);
+
+          if (!has_texture)
+            {
+              GTask *task = g_task_new (icon, NULL, NULL, NULL);
+              g_task_run_in_thread (task, load_icon_thread);
+              g_object_unref (task);
+            }
+        }
+    }
+
   return icon;
 }
 
index afc79e5a1860d43dcf5ed8d1f82dc396ff2fc9b9..f0fc704ed4001da06ac61583ee112bc7da8bfd55 100644 (file)
@@ -44,13 +44,16 @@ typedef struct _GtkIconTheme      GtkIconTheme;
  *   when symbolic icon names are given
  * @GTK_ICON_LOOKUP_FORCE_SYMBOLIC: Try to always load symbolic icons, even
  *   when regular icon names are given
+ * @GTK_ICON_LOOKUP_LOAD_IN_THREAD: Starts loading the texture in the background
+ *   so it is ready when later needed.
  *
  * Used to specify options for gtk_icon_theme_lookup_icon()
  */
 typedef enum
 {
   GTK_ICON_LOOKUP_FORCE_REGULAR    = 1 << 0,
-  GTK_ICON_LOOKUP_FORCE_SYMBOLIC   = 1 << 1
+  GTK_ICON_LOOKUP_FORCE_SYMBOLIC   = 1 << 1,
+  GTK_ICON_LOOKUP_LOAD_IN_THREAD   = 1 << 2,
 } GtkIconLookupFlags;
 
 /**